package com.uzai.console.web.dingding;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.uzai.common.dto.god.ExclusiveGroupOptDto;
import com.uzai.common.enums.RedisCacheKeyEnum;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.console.common.utils.DingCallbackCrypto;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.service.dingding.DingDingCallBackService;
import com.uzai.console.web.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@Api(value = "钉钉回调",tags = "钉钉回调")
@RestController
@RequestMapping("/dingDingCallBack")
public class DingDingCallBackController extends BaseController {

    private static Logger logger= LoggerFactory.getLogger(DingDingCallBackController.class);



    /**
     * 创建应用，验证回调URL创建有效事件（第一次保存回调URL之前）
     */
    private static final String EVENT_CHECK_CREATE_SUITE_URL = "check_create_suite_url";

    /**
     * 创建应用，验证回调URL变更有效事件（第一次保存回调URL之后）
     */
    private static final String EVENT_CHECK_UPADTE_SUITE_URL = "check_update_suite_url";

    /**
     * suite_ticket推送事件
     */
    private static final String EVENT_SUITE_TICKET = "suite_ticket";

    /**
     * 企业授权开通应用事件
     */
    private static final String EVENT_TMP_AUTH_CODE = "tmp_auth_code";

    @Autowired
    private RedisTemplate redisTemplate;

//    @Value("${dingding.exclusivegroup.aestoken}")
//    private String AES_TOKEN;
//
//    @Value("${dingding.exclusivegroup.aeskey}")
//    private String AES_KEY;

    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;

    @Autowired
    private DingDingCallBackService dingDingCallBackService;

    @PostMapping("/DingDingExclusiveGroupJoining")
    @ApiOperation(value = "钉钉专属服务器入群回调", notes = "钉钉专属服务器入群回调")
    @ApiOperationSupport(order = 1)
    public Object  DingDingExclusiveGroupJoining(  @RequestParam(value = "msg_signature") String msg_signature,
                                                 @RequestParam(value = "timestamp") String timeStamp,
                                                 @RequestParam(value = "nonce") String nonce,
                                                 @RequestBody(required = false) JSONObject body){

        String params = "msg_signature:" + msg_signature + " timestamp:" + timeStamp + " nonce:" + nonce + " body:" + body;

        try {
            logger.info("begin callback:" + params);

            //获取创建钉钉群的基本参数
            Object o = redisTemplate.opsForValue().get(RedisCacheKeyEnum.DING_DING_EXCLUSIVE_GROUP.getKey());
            if (o == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "获取钉钉专属服务群配置失败");
            }
            ExclusiveGroupOptDto ex = JSONObject.parseObject(o.toString(), ExclusiveGroupOptDto.class);


            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(uzaiConsoleSysConfig.getDingdingGroupAesToken(), uzaiConsoleSysConfig.getDingdingGroupAesKey(), ex.getAppKey());
            String encryptMsg = body.getString("encrypt");
            String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);

            // 反序列化回调事件json数据
            JSONObject eventJson = JSON.parseObject(decryptMsg);
            String eventType = eventJson.getString("EventType");
            logger.info("eventJson:"+eventJson);

            // 4. 根据EventType分类处理
            if ("check_url".equals(eventType)) {
                // 测试回调url的正确性
                logger.info("测试回调url的正确性");
            } else if ("servicegroup_contact_join_group_form".equals(eventType)||"chat_add_member".equals(eventType)) {

                // 服务群入群表单
                logger.info("发生了：" + eventType + "事件");
                String openConversationId  =eventJson.getString("OpenConversationId");
                logger.info("openConversationId:"+openConversationId);
                //扫码进入才修改
                if(eventJson.get("Operator")!=null){
                    dingDingCallBackService.chatAddMember(openConversationId);
                }
            } else {
                // 添加其他已注册的
                logger.info("发生了：" + eventType + "事件");
            }

            // 5. 返回success的加密数据
            Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
            JSONObject json = JSONObject.parseObject(JSON.toJSONString(successMap));
            System.out.println(json);
            return json;

        } catch (Exception e) {
            //失败的情况，应用的开发者应该通过告警感知，并干预修复
            logger.error("process callback fail." + params, e);
            return "fail";
        }
    }
}
